/**
 * 处理标签上的属性
 * 
 * @param {Object} vnode  虚拟 DOM
 */
function updateProps(vnode) {
	const el = vnode.el,
		newProps = vnode.data || {};

	for (const key in newProps) {
		if (key === "style") {
			for (const sKey in newProps.style) {
				el.style[sKey] = newProps.style[sKey];
			}
		} else if (key === "class") {
			el.className = newProps.class;
		} else {
			el.setAttribute(key, newProps[key]);
		}
	}
}

/**
 * 将虚拟 DOM 转换成真实 DOM
 * @param {*} vnode 虚拟节点
 */
function createEle(vnode) {
	const { tag, children, data: props, key, text } = vnode;

	// 如果是字符串
	if (typeof tag === "string") {
		// tag 如果是组件，需要判断处理
		console.log("标签是", vnode.tag, "属性是", vnode.data);
		// 如果是标签
		// 存放一份真实的 DOM，后续 diff 使用
		vnode.el = document.createElement(tag); // 后面需要 diff 算法，获取虚拟节点对比后更新 DOM
		updateProps(vnode); // 处理标签上的属性
		children &&
			children.forEach((child) => {
				// 递归处理子元素
				return vnode.el.appendChild(createEle(child));
			});
	} else {
		// 如果是文本
		// 存放一份真实的DOM，后续使用
		vnode.el = document.createTextNode(text);
	}
	return vnode.el;
}

/**
 * 通过虚拟节点（vnode）创建出真实节点
 *
 * @param {*} oldVnode 需要挂载的容器（更新的时候可能是一个旧的虚拟节点）
 * @param {*} vnode 新虚拟节点
 */
export function patch(oldVnode, vnode) {
	// console.log("patch", vnode);
	const isRealElement = oldVnode.nodeType; // 是一个 DOM 元素
	if (isRealElement) {
		const oldEle = oldVnode;
		// 获取父元素，将当前元素节点的下一个元素节点作为参照物，将它插入到老元素节点的前面即可，之后删除旧的元素节点
		const parentNode = oldEle.parentNode; // 父元素节点
		const el = createEle(vnode); // 根据虚拟节点生成真实 DOM 节点, 返回真实的 DOM 元素节点
		parentNode.insertBefore(el, oldEle.nextSibling);
		parentNode.removeChild(oldEle);
	}

	// diff 算法
}
